/*
 * Copyright 2008 Stuart Moffatt stuartmoffatt@gmail.com
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.googlecode.emcode.rvha.client.ui;

import java.util.ArrayList;
import java.util.HashMap;

import com.google.gwt.core.client.GWT;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONException;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.maps.client.MapPane;
import com.google.gwt.maps.client.MapPaneType;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.event.MapClickHandler;
import com.google.gwt.maps.client.event.MapDoubleClickHandler;
import com.google.gwt.maps.client.geom.LatLng;
import com.google.gwt.maps.client.overlay.GeoXmlLoadCallback;
import com.google.gwt.maps.client.overlay.GeoXmlOverlay;
import com.google.gwt.maps.client.overlay.Marker;
import com.google.gwt.maps.client.overlay.Overlay;
import com.google.gwt.maps.client.overlay.Polygon;
import com.google.gwt.maps.client.overlay.Polyline;
import com.google.gwt.user.client.Window;

public class HazardInformationHandler implements MapDoubleClickHandler {

    protected static final String KML_LIQUEFACTION = "http://hazards.utah.edu/slc/lqf005.kmz";
    protected static final String KML_DAM = "http://hazards.utah.edu/slc/damfailuresimple.kmz";
    
    /*
    private static final String MMI_VI = "Strong shaking: Felt by all, many frightened and run outdoors. Some heavy furniture moved; a few instances of fallen plaster and damaged chimneys. Damage light.";
    private static final String MMI_VII = "Very strong shaking - Negligible damage in buildings of good design and construction; slight to moderate in well-built ordinary structures; considerable in poorly built or designed structures.";
    private static final String MMI_VIII = "Severe shaking - Slight damage in specially designed structures; considerable in ordinary substantial buildings, with partial collapse; great in poorly built structures.";
    private static final String MMI_IX = "Violent shaking - Considerable damage in specially designed structures; well-designed frame structures thrown out of plumb; great in substantial buildings, with partial collapse.";
    */
    
    private static final String MMI_VI = "strong";
    private static final String MMI_VII = "very strong";
    private static final String MMI_VIII = "severe";
    private static final String MMI_IX = "violent";
    
    
    private Marker marker;
    private MapWidget map;
    private ArrayList polylines = new ArrayList();
    private HashMap mmiHash = new HashMap(); 
    
    public HazardInformationHandler()
    {
        super();
        initMMIHash();
    }
    
    private void initMMIHash() {
        /*
         * VI - Strong shaking: Felt by all, many frightened and run outdoors. Some heavy furniture moved; a few instances of fallen plaster and damaged chimneys. Damage light.
         * VI|VII - Strong or very strong shaking - (concat both)
         * VII - Very strong shaking - Neglible damage in buildings of good design and construction; slight to moderate in well-built ordinary structures; considerable in poorly built or designed structures.
         * VIII - Severe shaking - Slight damage in specially designed structures; considerable in ordinary substantial buildings, with partial collapse; great in poorly built structures. 
         * VIII|IX - Severe or violent shaking
         * IX - Violent shaking - Considerable damage in specially designed structures; well-designed frame structures thrown out of plumb; great in substantial buildings, with partial collapse
         */
        mmiHash.put("VI", MMI_VI);
        mmiHash.put("VII", MMI_VII);
        mmiHash.put("VIII", MMI_VIII);
        mmiHash.put("IX", MMI_IX);
        
        // the in betweens that can be either...
        mmiHash.put("VI|VII", MMI_VI + " or " + MMI_VII);
        mmiHash.put("VIII|IX", MMI_VIII + " or " + MMI_IX);
        
    }

    public void onDoubleClick(MapDoubleClickEvent e) {

        map = MainLayout.get().getMap();
        
        MapWidget sender = e.getSender();
        MapPane pane = sender.getPane(MapPaneType.MAP_PANE);
        // if this overlay is the damfailure, we get a null point
        LatLng point = e.getLatLng();
        
        // MainLayout.get().updateMarker(point);
        
        // now fetch the data from hazard_view_by_latlng
        fetchHazardInformation(point);
        
    }

    public void fetchHazardInformation(final LatLng point)
    {
//      convert point to strings for lat/lng
        String lat = Double.toString( point.getLatitude() );
        String lng = Double.toString( point.getLongitude() );
        
        String parms = "?lat=" + lat + "&lng=" + lng;
        
        RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.GET, "hazard_view_by_latlng.php" + parms);
        try
        {
          requestBuilder.setCallback(new RequestCallback(){
            

            public void onError(Request request, Throwable exception) {
                GWT.log(exception.getMessage(), null);
                //serverInfo.setText(exception.getMessage());
                
                //info.open(map.getCenter(), content);
            }

            public void onResponseReceived(Request request, Response response) {
                GWT.log(request.toString(), null);
                GWT.log(response.getText(), null);
                String req = request.toString();
                
                String resp = response.getText();
                
                String lat = "";
                String lng = "";
                String zip = "";
                
                String liquefaction = "";
                String damfailure = "";
                String mmi = "";
                
                String address = "";
                JSONObject parcel = null;
                
                try
                {
                    JSONValue jsonValue = JSONParser.parse(response.getText());
                    if( jsonValue.isObject() != null )
                    {
                        JSONObject o = jsonValue.isObject();
                        JSONValue locationValue = o.get("location");
                        JSONObject loc = locationValue.isObject();
                        
                        JSONValue latValue = loc.get("lat");
                        if( latValue != null && latValue.isString() != null )
                        {
                            lat = latValue.isString().stringValue();
                        }
                        
                        JSONValue lngValue = loc.get("lng");
                       
                        if( lngValue != null && lngValue.isString() != null )
                        {
                            lng = lngValue.isString().stringValue();
                        }                        
                        
                        JSONValue zipValue = loc.get("zipcode");
                        
                        if( zipValue != null && zipValue.isString() != null )
                        {
                            zip = zipValue.isString().stringValue();
                        }
                        
                        JSONValue mmiValue = loc.get("mmi");
                        
                        if( mmiValue != null && mmiValue.isString() != null )
                        {
                            mmi = mmiValue.isString().stringValue();
                        }
                        
                        JSONValue damfailureValue = loc.get("damfailure");
                        
                        if( damfailureValue != null && damfailureValue.isString() != null )
                        {
                            damfailure = lngValue.isString().stringValue();
                        }
                        
                        
                        JSONValue liquefactionValue = loc.get("liquefaction");
                        
                        if( liquefactionValue != null && liquefactionValue.isString() != null )
                        {
                            liquefaction = liquefactionValue.isString().stringValue();
                        }
                        
                        JSONValue parcelValue = loc.get("parcel");
                        
                        if( parcelValue != null && parcelValue.isObject() != null )
                        {
                            parcel = parcelValue.isObject();
                        }                        
                        
                        
                        if (parcel != null)
                        {
                            
                            // handle address
                            JSONValue addressValue = parcel.get("address");
                            if( addressValue != null && addressValue.isString() != null )
                            {
                                address = addressValue.isString().stringValue();
                            }  
                            
                            
                            // handle polygons
                            JSONArray polygonArray = (JSONArray) parcel.get("polygons");
                            if( polygonArray != null && polygonArray.isArray() != null)
                            {
                                for (int i = 0; i < polygonArray.size(); ++i)
                                {
                                    // handle polygons
                                    GWT.log("("+i+")" + polygonArray.get(i).toString(), null);
                                    if( polygonArray.get(i).isObject() != null)
                                    {
                                        JSONArray pointsArray = (JSONArray) polygonArray.get(i).isObject().get("points");
                                        int count = pointsArray.size();
                                        LatLng[] points = new LatLng[count];
                                        // handle points
                                        for (int j = 0; j < count; j++) {
                                            //GWT.log("["+j+"]" + pointsArray.get(j).toString(), null);
                                            JSONObject point = pointsArray.get(j).isObject();
                                            if( point != null)
                                            {
                                                String pointLat = point.get("lat").isString().stringValue();
                                                String pointLng = point.get("lng").isString().stringValue();
                                                
                                                LatLng p = new LatLng(
                                                                   Double.parseDouble(pointLat),
                                                                   Double.parseDouble(pointLng)
                                                                   );
                                                
                                                points[j] = p;
                                                
                                            }
                                        }
                                        // Polygon polygon = new Polygon(points);
                                        Polyline polyline = new Polyline(points);
                                        // polylines.add(polyline); // move to MainLayout?
                                        MainLayout.get().addParcelGeometry(polyline);
                                    }
                                    
                                }
                            }
                                
                        }

                        
                        GWT.log("good so far", null);
                        //JSONValue parcelValue = loc.get("parcel");
                        
                        
                        //Window.alert("Display the following: " + multiHazardsNode.toString());
                        /*
                        // handle zip
                        JSONValue zipValue = o.get("zip");
                        zipcode = zipValue.isString().stringValue();
                        
                        // handle parcel
                        JSONValue parcelValue = o.get("parcel");
                        parcel = parcelValue.isString().stringValue();
                        
                        JSONArray jsonHazards = (JSONArray) multiHazardsNode.isObject().get("hazards");
                        for (int i = 0; i < jsonHazards.size(); ++i)
                        {
                            // {"type":"liquefaction", "description":"Very Low"}
                            GWT.log(jsonHazards.get(i).toString(), null);
                            
                            String type = jsonHazards.get(i).isObject().get("type").isString().stringValue();
                            String description = jsonHazards.get(i).isObject().get("description").isString().stringValue();
                            
                            Hazard hazard = new Hazard();
                            hazard.setType(type);
                            hazard.setDescription(description);
                            
                            // put in the hash
                            hazards.put(hazard.getType(), hazard);
                            
                        }
                        */
                    }
                    
                }
                catch(JSONException e)
                {
                    Window.alert("parser error="+e.toString());
                }
                
                // build info window text
                String infoWindowText = "";
                
                if( address != null )
                {
                    infoWindowText += "<br><b>"+address+"</b> ";
                }
                
                if( zip != null )
                {
                    infoWindowText += "<b>"+zip+"</b>";
                }
                
                if( liquefaction != null || damfailure != null )
                {
                    infoWindowText += "<br>There are known hazards at this location:<ul>";
                }

                if( mmi != null )
                {
                    
                    // lookup MMI values for text description
                    String mmiDescription = (String) mmiHash .get(mmi);
                    infoWindowText += "<li>This area may feel <b>"+mmiDescription+"</b> shaking in a 7.0 earthquake";
                }
                
                if( liquefaction != null )
                {
                    infoWindowText += "<li>The liquefaction potential is <b>"+liquefaction+"</b></li>";
                }
                
                if( damfailure != "" )
                {
                    infoWindowText += "<li>You are in a potential dam failure area</li>";
                }
                else
                {
                    infoWindowText += "<li>You are <u>not</u> in a potential dam failure area</li>";
                }
                
                // now add the marker
                MainLayout.get().updateMarker(point, infoWindowText);
                
            }
              
          });
          requestBuilder.send();
      } catch (RequestException e) {
          e.printStackTrace();
      }
      
    }
    
    
}
